home *** CD-ROM | disk | FTP | other *** search
Text File | 2000-10-06 | 10.7 KB | 521 lines | [TEXT/CWIE] |
- ///--------------------------------------------------------------------------------------
- // BlitPixieFlip
- // a fast horizontal-flipping blitter
- //
- // for vertical-flipping, use normal BlitPixie with last pixel row and negative rowBytes
- //
- // written by Anders F Björklund <afb@algonet.se>
- // © 1999 afb.
- ///--------------------------------------------------------------------------------------
-
- #ifndef __BLITPIXIE__
- #include "BlitPixieHeader.h"
- #endif
-
- #include "BlitPixieAsm.h"
-
- #pragma mark *** PowerPC asm:
- #if USE_PPC_ASSEMBLY
-
- ASM_FUNC void BlitPixieFlip8Bit(
- register unsigned char *source, register unsigned char *destination,
- register unsigned long srcRowBytes, register unsigned long dstRowBytes,
- register unsigned short width, register unsigned short height)
- {
- #define r_srcPixel r3
- #define r_dstPixel r4
- #define r_srcOffset r5
- #define r_dstOffset r6
- #define r_width r7
- #define r_rows r8
-
- #define r_words r9
- #define r_index1 r10
- #define r_index2 r11
-
- ASM_BEGIN
-
- rlwinm r_index1,r_width,0,31,31 // numBytesPerRow & 1
- rlwinm r_index2,r_width,31,31,31 // numBytesPerRow & 2
- rlwinm r_words,r_width,30,2,31 // numBytesPerRow >> 2
-
- cmplwi cr7,r_index1,0
- cmplwi cr6,r_index2,0
- cmplwi cr5,r_words,0
-
- @yloop:
-
- mr r_index1,r_width
- li r_index2,0
-
- beq cr5,@skipwords
- mtctr r_words
- @wordloop:
- subi r_index1,r_index1,4
- lwbrx r0,r_srcPixel,r_index1
- stwx r0,r_dstPixel,r_index2
- addi r_index2,r_index2,4
- bdnz @wordloop
- @skipwords:
-
- beq cr6,@skipshort
- subi r_index1,r_index1,2
- lhbrx r0,r_srcPixel,r_index1
- sthx r0,r_dstPixel,r_index2
- addi r_index2,r_index2,2
- @skipshort:
-
- beq cr7,@skipbyte
- subi r_index1,r_index1,1
- lbzx r0,r_srcPixel,r_index1
- stbx r0,r_dstPixel,r_index2
- addi r_index2,r_index2,1
- @skipbyte:
-
- subic. r_rows,r_rows,1
-
- add r_srcPixel,r_srcPixel,r_srcOffset
- add r_dstPixel,r_dstPixel,r_dstOffset
-
- bne @yloop
-
- ASM_END
- }
-
- ASM_FUNC void BlitPixieFlip16Bit(
- register unsigned short *source, register unsigned short *destination,
- register unsigned long srcRowBytes, register unsigned long dstRowBytes,
- register unsigned short width, register unsigned short height)
- {
- #define r_srcPixel r3
- #define r_dstPixel r4
- #define r_srcOffset r5
- #define r_dstOffset r6
- #define r_bytes r7
- #define r_rows r8
-
- #define r_words r9
- #define r_index1 r10
- #define r_index2 r11
-
- ASM_BEGIN
-
- add r_bytes,r_bytes,r_bytes
-
- rlwinm r_index2,r_bytes,31,31,31 // numBytesPerRow & 2
- rlwinm r_words,r_bytes,30,2,31 // numBytesPerRow >> 2
-
- cmplwi cr6,r_index2,0
- cmplwi cr5,r_words,0
-
- @yloop:
-
- mr r_index1,r_bytes
- li r_index2,0
-
- beq cr5,@skipwords
- mtctr r_words
- @wordloop:
- subi r_index1,r_index1,4
- lwzx r0,r_srcPixel,r_index1
- rlwinm r12,r0,16,0,15
- rlwimi r12,r0,16,16,31
- stwx r12,r_dstPixel,r_index2
- addi r_index2,r_index2,4
- bdnz @wordloop
- @skipwords:
-
- beq cr6,@skipshort
- subi r_index1,r_index1,2
- lhbrx r0,r_srcPixel,r_index1
- sthx r0,r_dstPixel,r_index2
- addi r_index2,r_index2,2
- @skipshort:
-
- subic. r_rows,r_rows,1
-
- add r_srcPixel,r_srcPixel,r_srcOffset
- add r_dstPixel,r_dstPixel,r_dstOffset
-
- bne @yloop
-
- ASM_END
- }
-
- #pragma mark *** 680x0 asm:
- #elif USE_68K_ASSEMBLY
-
- ASM_FUNC void BlitPixieFlip8Bit(
- unsigned char *source, unsigned char *destination,
- unsigned long srcBytes, unsigned long dstBytes,
- unsigned short width, unsigned short height )
- {
- #define A_src A0
- #define A_dst A1
-
- #define D_srcRowBytes D3
- #define D_dstRowBytes D4
- #define D_x D5
- #define D_y D6
-
- #define D_longs D2
-
- ASM_BEGIN
- MOVEM.L D3-D6,-(SP)
-
- MOVEM.L source,A0-A1
- MOVEM.L srcBytes,D3-D6
-
- MOVE.W D_x,D_longs
- LSR.W #2,D_longs
-
- ADD.L D_x,D_srcRowBytes
- SUB.L D_x,D_dstRowBytes
-
- ADDA.L D_x,A0
- SUBQ.W #1,D_longs
-
- @rowloop:
-
- MOVE.W D_longs,D1
- BMI @skiploop
- @longwordloop:
- MOVE.L -(A0),D0
- ROR.W #8,D0
- SWAP D0
- ROR.W #8,D0
- MOVE.L D0,(A1)+
- DBRA D1,@longwordloop
- @skiploop:
-
- MOVE.W D_x,D1
- ANDI.W #2,D1
- BEQ.S @skipword
- MOVE.W -(A0),D0
- ROR.W #8,D0
- MOVE.W D0,(A1)+
- @skipword:
-
- MOVE.W D_x,D1
- ANDI.W #1,D1
- BEQ.S @skipbyte
- MOVE.B -(A0),(A1)+
- @skipbyte:
-
- ADDA.L D_srcRowBytes,A0
- ADDA.L D_dstRowBytes,A1
-
- SUBQ.W #1,D_y
- BNE @rowloop
-
- MOVEM.L (SP)+,D3-D6
- ASM_END
- }
-
- ASM_FUNC void BlitPixieFlip16Bit(
- unsigned short *source, unsigned short *destination,
- unsigned long srcBytes, unsigned long dstBytes,
- unsigned short width, unsigned short height )
- {
- #define A_src A0
- #define A_dst A1
-
- #define D_srcRowBytes D3
- #define D_dstRowBytes D4
- #define D_x D5
- #define D_y D6
-
- #define D_longs D2
-
- ASM_BEGIN
- MOVEM.L D3-D6,-(SP)
-
- MOVEM.L source,A0-A1
- MOVEM.L srcBytes,D3-D6
-
- ADD.W D_x,D_x
-
- MOVE.W D_x,D_longs
- LSR.W #2,D_longs
-
- ADD.L D_x,D_srcRowBytes
- SUB.L D_x,D_dstRowBytes
-
- ADDA.L D_x,A0
- SUBQ.W #1,D_longs
-
- @rowloop:
-
- MOVE.W D_longs,D1
- BMI @skiploop
- @longwordloop:
- MOVE.L -(A0),D0
- SWAP D0
- MOVE.L D0,(A1)+
- DBRA D1,@longwordloop
- @skiploop:
-
- MOVE.W D_x,D1
- ANDI.W #2,D1
- BEQ.S @skipword
- MOVE.W -(A0),D0
- ROR.W #8,D0
- MOVE.W D0,(A1)+
- @skipword:
-
- ADDA.L srcBytes,A0
- ADDA.L dstBytes,A1
-
- SUBQ.W #1,D_y
- BNE @rowloop
-
- MOVEM.L (SP)+,D3-D6
- ASM_END
- }
-
- #pragma mark *** Generic C:
- #elif USE_GENERIC_C
-
- void BlitPixieFlip8Bit(
- unsigned char *src, unsigned char *dst,
- unsigned long srcRowBytes, unsigned long dstRowBytes,
- unsigned short width, unsigned short height)
- {
- unsigned long x,y;
-
- srcRowBytes += width;
- dstRowBytes -= width;
-
- src += width;
-
- for ( y = 0; y < height; y++ )
- {
- for ( x = 0; x < width; x++ )
- *dst++ = *--src;
-
- src += srcRowBytes;
- dst += dstRowBytes;
- }
- }
-
- void BlitPixieFlip16Bit(
- unsigned short *src, unsigned short *dst,
- unsigned long srcRowBytes, unsigned long dstRowBytes,
- unsigned short width, unsigned short height)
- {
- unsigned long x,y;
-
- srcRowBytes += width << 1;
- dstRowBytes -= width << 1;
-
- src += width;
-
- for ( y = 0; y < height; y++ )
- {
- for ( x = 0; x < width; x++ )
- *dst++ = *--src;
-
- src = (unsigned short *) ( (char *) src + srcRowBytes);
- dst = (unsigned short *) ( (char *) dst + dstRowBytes);
- }
- }
-
- #endif
-
- #ifndef GENERATINGASM // do not include for asm file generation
-
- // no much use doing this routine in asm, since everything is longs already
- void BlitPixieFlip32Bit(
- unsigned long *src, unsigned long *dst,
- unsigned long srcRowBytes, unsigned long dstRowBytes,
- unsigned short width, unsigned short height)
- {
- unsigned long x,y;
-
- srcRowBytes += width << 2;
- dstRowBytes -= width << 2;
-
- src += width;
-
- for ( y = 0; y < height; y++ )
- {
- for ( x = 0; x < width; x++ )
- *dst++ = *--src;
-
- src = (unsigned long *) ( (char *) src + srcRowBytes);
- dst = (unsigned long *) ( (char *) dst + dstRowBytes);
- }
- }
-
- #pragma mark -
- #pragma mark *** Masked blitters ***
-
- void BlitPixieFlipMask8Bit(
- unsigned char *src, unsigned char *dst, unsigned char *mask,
- unsigned long srcRowBytes, unsigned long dstRowBytes,
- unsigned short width, unsigned short height)
- {
- unsigned long x,y;
- unsigned char m;
-
- srcRowBytes += width;
- dstRowBytes -= width;
-
- src += width;
- mask += width;
-
- for ( y = 0; y < height; y++ )
- {
- for ( x = 0; x < width; x++ )
- {
- m = *--mask;
- *dst++ = (*dst & m) | (*--src &~ m);
- }
-
- src += srcRowBytes;
- mask += srcRowBytes;
- dst += dstRowBytes;
- }
- }
-
- void BlitPixieFlipMask16Bit(
- unsigned short *src, unsigned short *dst, unsigned short *mask,
- unsigned long srcRowBytes, unsigned long dstRowBytes,
- unsigned short width, unsigned short height)
- {
- unsigned long x,y;
- unsigned short m;
-
- srcRowBytes += width << 1;
- dstRowBytes -= width << 1;
-
- src += width;
- mask += width;
-
- for ( y = 0; y < height; y++ )
- {
- for ( x = 0; x < width; x++ )
- {
- m = *--mask;
- *dst++ = (*dst & m) | (*--src &~ m);
- }
-
- src = (unsigned short *) ( (char *) src + srcRowBytes);
- mask = (unsigned short *) ( (char *) mask + srcRowBytes);
- dst = (unsigned short *) ( (char *) dst + dstRowBytes);
- }
- }
-
- void BlitPixieFlipMask32Bit(
- unsigned long *src, unsigned long *dst, unsigned long *mask,
- unsigned long srcRowBytes, unsigned long dstRowBytes,
- unsigned short width, unsigned short height)
- {
- unsigned long x,y;
- unsigned long m;
-
- srcRowBytes += width << 2;
- dstRowBytes -= width << 2;
-
- src += width;
- mask += width;
-
- for ( y = 0; y < height; y++ )
- {
- for ( x = 0; x < width; x++ )
- {
- m = *--mask;
- *dst++ = (*dst & m) | (*--src &~ m);
- }
-
- src = (unsigned long *) ( (char *) src + srcRowBytes);
- mask = (unsigned long *) ( (char *) mask + srcRowBytes);
- dst = (unsigned long *) ( (char *) dst + dstRowBytes);
- }
- }
-
-
- // note: mask #1 is straight, mask #2 is flipped.
- // if both are flipped, use the normal collision-test instead
- Boolean BlitPixieFlipMaskCollision(
- unsigned char *maskPtr1, unsigned char *maskPtr2,
- unsigned long rowBytes1, unsigned long rowBytes2,
- unsigned short bytes, unsigned short rows)
- {
- unsigned long x;
-
- rowBytes1 -= bytes;
- maskPtr2 += bytes;
-
- while ( rows-- )
- {
- for ( x = 0; x < bytes; x++)
- {
- if ( (*maskPtr1++ | *--maskPtr2) == 0 )
- return true;
- }
-
- maskPtr1 += rowBytes1;
- maskPtr2 += rowBytes2;
- }
-
- return false;
- }
-
- void BlitPixieFlipMaskColor(
- unsigned long srcColor, unsigned char *dstPixelP, unsigned char *maskPixelP,
- unsigned long srcRowBytes, unsigned long dstRowBytes,
- unsigned short bytes, unsigned short rows )
- {
- unsigned long index;
- unsigned long mask;
-
- srcRowBytes += bytes;
- dstRowBytes -= bytes;
-
- maskPixelP += bytes;
-
- while (rows--)
- {
- // note: must do this with longs and shorts first, since depth can be both 32, 16 or 8 bits
-
- for (index=0; index < (bytes>>2); index++)
- {
- maskPixelP -= sizeof(unsigned long);
- #if USE_PPC_ASSEMBLY
- mask = __lwbrx( maskPixelP, 0 );
- #else
- mask = *((unsigned long *) maskPixelP);
- mask = ((mask >> 24) & 0xFF) | ((mask >> 8) & 0xFF00) | ((mask & 0xFF00) << 8) | ((mask & 0xFF) << 24);
- #endif
- *((unsigned long *) dstPixelP) = (*((unsigned long *) dstPixelP) & mask) | (srcColor &~ mask);
- dstPixelP += sizeof(unsigned long);
- }
-
- if ( bytes & 2 )
- {
- maskPixelP -= sizeof(unsigned short);
- #if USE_PPC_ASSEMBLY
- mask = __lhbrx( maskPixelP, 0 );
- #else
- mask = *((unsigned short *) maskPixelP);
- mask = (mask >> 8) & 0x00FF | ( (mask << 8) & 0xFF00 );
- #endif
- *((unsigned short *) dstPixelP) = (*((unsigned short *) dstPixelP) & mask) | (srcColor &~ mask);
- dstPixelP += sizeof(unsigned short);
- }
-
- if ( bytes & 1 )
- {
- mask = *--maskPixelP;
- *dstPixelP++ = (*dstPixelP & mask) | (srcColor &~ mask);
- }
-
- // bump to next row
- dstPixelP += dstRowBytes;
- maskPixelP += srcRowBytes;
- }
- }
-
- #endif
-